package databook;

import java.awt.geom.Point2D;
import java.util.Iterator;

import prefuse.Constants;
import prefuse.data.Edge;
import prefuse.data.Node;
import prefuse.render.EdgeRenderer; 
import prefuse.visual.EdgeItem; 

/**
 * Multi-edge renderer
 * 
 * Based on examples found at http://sourceforge.net/forum/forum.php?thread_id=2011671&forum_id=343013
 *
 */
public class FlowEdgeRenderer extends EdgeRenderer 
{ 
 
	/**
	 * constructor that takes in the curve type and arrow type 
	 * @param edgeTypeCurve
	 * @param edgeArrowForward
	 */
	public FlowEdgeRenderer() 
	{ 
		super(Constants.EDGE_TYPE_CURVE, Constants.EDGE_ARROW_FORWARD); 
	} 
	 
	/**
	 * 
	 */
	protected void getCurveControlPoints(EdgeItem eitem, Point2D[] cp, 
	double x1, double y1, double x2, double y2) 
	{ 
		// how many from '1' to '2'? 
		Node sourceNode = eitem.getSourceNode(); 
		Node targetNode = eitem.getTargetNode(); 
		Iterator edges = sourceNode.edges(); 
		 
		// number of equal edges = same target and source 
		int noOfEqualEdges = 0; 
		// number of nearequal edges = same nodes, but any order target 
		// and source 
		int noOfSameNodeEdges = 0; 
		int myEdgeIndex = 0; 
		int row = eitem.getRow(); 
		while (edges.hasNext()) 
		{ 
			Edge edge = (Edge) edges.next(); 
			int edgeRow = edge.getRow(); 
			if (edge.getSourceNode() == sourceNode 
					&& edge.getTargetNode() == targetNode) 
			{ 
				if (row == edgeRow) 
				{ 
					myEdgeIndex = noOfEqualEdges; 
				} 
				noOfEqualEdges++; 
				noOfSameNodeEdges++; 

			} 
			else if (edge.getSourceNode() == targetNode 
					&& edge.getTargetNode() == sourceNode) 
			{ 

				noOfSameNodeEdges++; 
			} 
		}
		
		double dx = x2 - x1; 
		double dy = y2 - y1; 
	 
		// modify to add an offset relative to what this edge's index is 
		// 0 = straight line, 1 is default, 2+ skews the line downward at the start
		dx = dx * (1 + myEdgeIndex);  
		dy = dy * (1 + myEdgeIndex); 
	 
		// dx/3 is default, dx/6 tightens the lines to each other 
		cp[0].setLocation(x1 + 2 * dx / 2, y1); 
		cp[1].setLocation(x2 - dx / 10, y2 - dy / 8); 
		 
		// draw the line straight if we found one edge 
		//if (myEdgeIndex == 0 && noOfSameNodeEdges == 1) 
		//{ 
		//	cp[0].setLocation(x2, y2); 
		//	cp[1].setLocation(x1, y1); 
		//} 
	} 
}